package com.eastfair.imaster.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.cache.operations.SpeakerCacheKeyBuilder;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.constant.EntityAttributeString;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.utils.AssembleOrderBySqlUtils;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.core.utils.StringUtils;
import com.eastfair.enums.SortTypeEnum;
import com.eastfair.imaster.dao.SpeakerMapper;
import com.eastfair.imaster.dto.SpeakerDTO;
import com.eastfair.imaster.dto.SpeakerPageQuery;
import com.eastfair.imaster.entity.Speaker;
import com.eastfair.imaster.enumeration.SortOrderTypeEnum;
import com.eastfair.imaster.service.SpeakerService;
import com.eastfair.imaster.vo.SpeakerVO;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 业务实现类
 * 嘉宾
 * </p>
 *
 * @author zjn
 * @date 2021-08-31
 */
@Slf4j
@Service
@DS("#thread.tenant")
public class SpeakerServiceImpl extends SuperCacheServiceImpl<SpeakerMapper, Speaker> implements SpeakerService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;
    @Autowired
    private SpeakerMapper speakerMapper;

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new SpeakerCacheKeyBuilder();
    }

    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(Speaker entity) {
        UpdateWrapper<Speaker> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(Speaker::getProjectId, entity.getProjectId()).eq(Speaker::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(Speaker model) {
        //雪花ID
        model.setId(DefaultUidGenerator.getUidOfProjectId(ContextUtil.getProjectId()));
        model.setProjectId(ContextUtil.getProjectId());
        return R.successDef();
    }

    @Override
    public Boolean deleteById(Long id) {
        Speaker speaker = new Speaker();
        speaker.setId(id);
        speaker.setProjectId(ContextUtil.getProjectId());
        speaker.setIsDeleted(BusinessConstant.DELETE_YES);
        return updateByIdOfShard(speaker);
    }

    @Override
    public Boolean updateById(SpeakerDTO speakerDTO) {
        Speaker speaker = BeanUtil.copyProperties(speakerDTO, Speaker.class);
        speaker.setProjectId(ContextUtil.getProjectId());
        return updateByIdOfShard(speaker);
    }

    @Override
    public SpeakerVO queryById(Long id) {
        QueryWrapper<Speaker> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Speaker::getProjectId, ContextUtil.getProjectId()).eq(Speaker::getId, id);
        Speaker speaker = getOne(wrapper, false);
        return BeanUtil.copyProperties(speaker, SpeakerVO.class);
    }

    @Override
    public Page<SpeakerVO> queryPageList(PageParams<SpeakerPageQuery> params) {
        SpeakerDTO speakerDTO = BeanUtil.copyProperties(params.getModel(), SpeakerDTO.class);
        QueryWrapper<Speaker> speakerQueryWrapper = assembleListQueryWrapper(speakerDTO);
        Page<Speaker> speakerPage = page(params.buildPage(), speakerQueryWrapper);
        return ConvertUtil.convertPage(speakerPage, SpeakerVO.class);
    }

    @Override
    public List<SpeakerVO> queryList(SpeakerDTO speakerDTO) {
        QueryWrapper<Speaker> speakerQueryWrapper = assembleListQueryWrapper(speakerDTO);
        return ConvertUtil.convertList(list(speakerQueryWrapper), SpeakerVO.class);
    }

    @Override
    public List<SpeakerVO> getByIdList(List<Long> idList, String sortOrderType) {
        if (idList == null || idList.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        return ConvertUtil.convertList(list(assembleQueryWrapper(idList, sortOrderType)), SpeakerVO.class);
    }

    @Override
    public Page<SpeakerVO> getPageByIdList(PageParams<SpeakerPageQuery> params, List<Long> idList, String sortOrderType) {
        if (idList == null || idList.isEmpty()) {
            return new Page<>();
        }
        return ConvertUtil.convertPage(page(params.buildPage(), assembleQueryWrapper(idList, sortOrderType)), SpeakerVO.class);
    }

    /**
     * 特殊排序处理查询 -- 组装查询条件
     *
     * @param idList        需要查询的数据id
     * @param sortOrderType 排序方式
     * @return 查询条件
     */
    private QueryWrapper<Speaker> assembleQueryWrapper(List<Long> idList, String sortOrderType) {
        QueryWrapper<Speaker> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(Speaker::getId, idList).eq(Speaker::getProjectId, ContextUtil.getProjectId())
                .select(Speaker.class, info -> !info.getColumn().equals(EntityAttributeString.INTRODUCE)
                        && !info.getColumn().equals(EntityAttributeString.EN_INTRODUCE));
        ;

        if (SortOrderTypeEnum.MANUAL.eq(SortOrderTypeEnum.get(sortOrderType))) {
            // 按照id顺序排序
            queryWrapper.lambda().last(AssembleOrderBySqlUtils.assembleField(EntityAttributeString.ID, idList));
        } else {
            // 按照自动顺序排序
            queryWrapper.lambda().last(AssembleOrderBySqlUtils.assembleConvert(EntityAttributeString.NAME, EntityAttributeString.EN_NAME, SortTypeEnum.ASC.name()));
        }
        return queryWrapper;
    }

    /**
     * 列表查询条件拼接
     *
     * @param speakerDTO 条件实体
     * @return 列表查询条件
     */
    private QueryWrapper<Speaker> assembleListQueryWrapper(SpeakerDTO speakerDTO) {
        QueryWrapper<Speaker> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Speaker::getProjectId, ContextUtil.getProjectId())
                .eq(Speaker::getIsDeleted, BusinessConstant.DELETE_NO)
                .orderByDesc(Speaker::getUpdateTime)
                .select(Speaker.class, info -> !info.getColumn().equals(EntityAttributeString.INTRODUCE)
                        && !info.getColumn().equals(EntityAttributeString.EN_INTRODUCE));

        // 条件拼接
        if (!Objects.isNull(speakerDTO)) {
            if (!Objects.isNull(speakerDTO.getIsEnabled())) {
                wrapper.lambda().eq(Speaker::getIsEnabled, speakerDTO.getIsEnabled());
            }
            if (!StringUtils.isBlank(speakerDTO.getSearchKeywords())) {
                wrapper.lambda().and(likeWrapper -> likeWrapper.like(Speaker::getName, speakerDTO.getSearchKeywords())
                        .or().like(Speaker::getEnName, speakerDTO.getSearchKeywords())
                        .or().like(Speaker::getCompanyName, speakerDTO.getSearchKeywords())
                        .or().like(Speaker::getCompanyEnName, speakerDTO.getSearchKeywords())
                );
            }
        }
        return wrapper;
    }

}
